/**
 * RUP Grid/ JqGrid module - /public/js/grid.rup.js
 *
 * @module grid
 */


/**
 * TODO: already exists
 */
Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
};


/**
 * Get internal columns: NON-UI columns
 *
 * @class gridInternalColumns
 * @constructor
 * @return {Array} Get internal columns: NON-UI columns
 */
var gridInternalColumns = function () {
    res = JSSettings.grid.internalColumns.split(",");
    return res;
};

/**
 * Add pure JqGrid without data for administration purposes(s. gridConfig())
 *
 * @class addBasicGrid
 * @constructor
 * @param {String} gridId
 * @param {Integer} orgId
 * @param {Integer} level
 */
function addBasicGrid(gridId, orgId, level) {

    var url = "/"+lang+"/admin/settings/ajaxc-get-base-grid?gridid=" + gridId + '&orgid=' + orgId + '&level=' + level;
    $.ajax({
            url: url,
            dataType: 'json',
            success: function(responseData){
                $("#gridDialogBox").empty().html(responseData.content);
                //$(".ui-state-default.ui-jqgrid-hdiv").css('overflow', 'auto');
            }
    });
}

function gridNewEntry(url)
{
    if(url)
        location.href = url;
    else
        location.href = "edit";

    // showFormDialog(0);
}

function gridEditEntry(id)
{
    location.href = "edit?id="+id;
    // showFormDialog(id);
}

/**
 * Stanard JS funtion for JqGrid column editing: order, show/Hide
 *
 * @class gridShowHideCols
 * @constructor
 * @event reloadGrid
 * @param {String} gridId Grids unique ID
 * @param {String} urlGridRenderer
 */
function gridShowHideCols(gridId, urlGridRenderer){
    var but_ok      = translate.t('JVS_BUT_OK');
    var but_cancel  = translate.t('JVS_BUT_CANCEL');
    var buttons     = {};
    buttons[but_ok] = function() {
                       //dataSer = $('#formGridShowHide').serialize();
                       var dataSer = "gridid=" + gridId + "&editColumns=editColumns&";
                       var countOfInternalCols = gridCountOfInternalColumns(gridId);
                       var remapColumns =   countOfInternalCols > 0 ? createCSNumeration(countOfInternalCols-1) : "0";

                       var mapVisibleCols2Order = {};
                       var arVisibleCols = new Array();
                       var counterVisibleCols = countOfInternalCols > 0 ? countOfInternalCols  : 1;

                       $('#sortable-grid-list li input[type=checkbox]').each(function(index) {
                           isOn = $(this).attr('checked') ? "1" : "0";
                           colIndex = $(this).attr('id');
                           if(isOn == "1")
                               arVisibleCols.push(colIndex);
                               //    mapVisibleCols2Order[colIndex] = counterVisibleCols++;
                           dataSer += colIndex + "=" + isOn + "&";
                       });
                       defaultColModel = $("#"+gridId).jqGrid("getGridParam", "defaultColModelOrderMap");
                       jQuery.each(defaultColModel, function(name, value) {
                           if($.inArray(name, arVisibleCols) > -1)
                               mapVisibleCols2Order[name] = counterVisibleCols++;
                       });
                       for(var i=0; i<arVisibleCols.length; i++) {
                           remapColumns += ',' + mapVisibleCols2Order[arVisibleCols[i]] ;
                       }
                       var re = /&$/;
                       var regExComma = /,$/;

                       dataSer = dataSer.replace(re, "");
                       dataSer += "&remapColumns=" + remapColumns;
                       trace("[GRID] remapColumns: " + dataSer);

                       $.ajax({
                           url: $('#formGridShowHide').attr('action'),
                           type: 'POST',
                           dataType: "json",
                           data: dataSer,
                           success: function(data){
                                       if(data.message.toLowerCase() == "ok"){
                                           if(typeof reloadGridCallBack == 'function') {
                                               trace("[GRID] reloadGridCallBack found");
                                               reloadGridCallBack(gridId,data);
                                           } else {
                                               trace("[GRID] reloadGridCallBack NOT found");
                                               reloadGrid(gridId, urlGridRenderer);
                                           }
                                           //reloadGridCallBack(gridId,data);
                                           // location.reload();//$('#customergrid').trigger("reloadGrid");
                                       }
                                    }
                           });
                       $( this ).dialog( "close" );
                       //$('#main_content').trigger('reloadGrid', [gridId]);
                   };
   buttons[but_cancel] = function() {
       $( this ).dialog( "close" );
   };
    $.ajax({
        url: '/' + lang + '/application/config/ajaxc-grid-cols?gridid=' + gridId,
        type: 'GET',
        dataType: "json",
        context: document.body,
        success: function(data){
            if(data.error) {
                alert(translate.t("INF_ERROR_UNEXPECTED"));
                return;
            }
            $('<div id="boxShowHideColumns" style="padding: 6px;"></div>').html(data.message).
                dialog({
                        modal: true,
                        title: data.title,
                        resizable: false,
                        close:function(){$( this ).remove();},
                        buttons : buttons
                        });
            $("#sortable-grid-list").sortable({ handle: '.sortableHandle', axis: 'y' }).find(".sortableHandle").button({ text: false, icons: {primary:'ui-icon-arrowthick-2-n-s'} });;
            $("#ssortable-grid-list").disableSelection();
        }
      });
}


/**
 * Stanard JS funtion for reloading a grid
 *
 * @class reloadGrid
 * @constructor
 * @param {String} gridId Grids unique ID
 * @param {String} urlGridRenderer
 */
var reloadGrid = function(gridId, urlGridRenderer) {
    curUrl = (urlGridRenderer != "undefined" && urlGridRenderer != null && urlGridRenderer) ? urlGridRenderer : "/" + lang + "/application/config/ajaxc-get-grid?gridid=" + gridId;
    $.ajax({
        url: curUrl,
        dataType: "json",
        success: function(data){
                    if(data.error == "") {
                        $("#"+gridId+"_wrapper").empty();
                        $("#"+gridId+"_wrapper").html(data.message);
                    };
                    //if(data.message.toLowerCase() == "ok"){location.reload();//$('#customergrid').trigger("reloadGrid");}
                 }
        });

};

var loadGrid = function(gridId, parentId, url, callback) {
    curParentId = (parentId != "undefined" && parentId != null && parentId) ? parentId : gridId + "_wrapper";
    curUrl = (url != "undefined" && url != null && url) ? url : "/" + lang + "/application/config/ajaxc-get-grid?gridid=" + gridId;
    $.ajax({
        url: curUrl,
        dataType: "json",
        success: function(data){
                    if(data.error == "") {
                        if (data.curParentId) {
                          curParentId = data.curParentId;
                        }

                        $("#" + curParentId).empty();
                        $("#" + curParentId).html(data.message);
                        if (typeof callback == 'function') {
                            callback(data, gridId, parentId);
                        }
                    };
                 }
        });
};

/**
 * Renders a column config dialog(show/hide, order) with OK/Cancel buttons
 *
 * @class adminGridShowHideCols
 * @constructor
 * @param {String} gridId Grids unique ID
 */
function adminGridShowHideCols(gridId){
    var idGrid = "#" + gridId;
    var but_ok      = translate.t('JVS_BUT_OK');
    var but_cancel  = translate.t('JVS_BUT_CANCEL');
    var buttons     = {};
    var mColModel = $(idGrid).jqGrid("getGridParam", "colModel");
    var mColNames = $(idGrid).jqGrid("getGridParam", "colNames");

    buttons[but_ok] = function() {
        var countOfInternalCols = gridCountOfInternalColumns(gridId);
        var remapColums =   countOfInternalCols > 0 ? createCSNumeration(countOfInternalCols-1, true) : new Array(0);
        $('#sortable-grid-list li input[type=checkbox]').each(function(index) {
            pos = getColPosInColModel(mColModel, $(this).attr('name'));
            remapColums.push(pos);
            //mColModel[pos].hidden = isChecked;
            isChecked = $(this).attr('checked') ? true : false;
            if(isChecked == true)
                $(idGrid).jqGrid("showCol", $(this).attr('name'));
            else
                $(idGrid).jqGrid("hideCol", $(this).attr('name'));
        });
        trace("[GRID] remapColumns: " +remapColums);
        //jQuery(idGrid).jqGrid("setGridParam", "remapColumns", remapColums.join(","));
        //jQuery(idGrid).setGridParam({remapColumns: remapColums});
        $('#' + gridId).jqGrid('remapColumns', remapColums, true, false);
        gridComplete();
        $( this ).dialog( "close" );
    };
    buttons[but_cancel] = function() {
       $( this ).dialog( "close" );

    };
    var content = '<form id="formGridShowHide">';
    content +=    '<ul id="sortable-grid-list">';

    var append = "";
    internalCols = gridInternalColumns();
    $.each(mColModel,function(index,column){
        var colId = column.index ? column.index : column.name;
        if(internalCols.contains(colId) || column.name == 'cb')
            return;
        var checked= "";
        if(column.hidden == false)
            checked='checked="checked"';
        var htmlLi ='<li><input type="checkbox" class="checkboxSwitcher" ' + checked +
                ' id="colchk_'+colId+'" name="'+colId +'" value="" />' + translate.t(mColNames[index]) + '<span class="sortableHandle"></span></li>';
        if(column.hidden == false)
            content += htmlLi;
        else
            append += htmlLi;
    });

    content += append + '</ul></form>';
    $('<div id="boxShowHideColumns" style="padding: 6px;"></div>').html(content).
    dialog({
           modal: false,
           closeOnEscape: true,
           stack: true,
           close:function(){ $( this ).remove(); },
           title: translate.t('JVS_HIDE_SHOW_COLUMS'),
           resizable: false,
           buttons : buttons
    });

    $("#sortable-grid-list").sortable({ handle: '.sortableHandle', axis: 'y' }).find(".sortableHandle").button({ text: false, icons: {primary:'ui-icon-arrowthick-2-n-s'} });
    $("#ssortable-grid-list").disableSelection();

}


/**
 * Helper: Get Position of colName in JqGrids "colModel"
 *
 * @class getColPosInColModel
 * @constructor
 * @param {Array} colModel
 * @param {String} colName
 */
var getColPosInColModel = function(colModel, colName) {
    for (var i = 0; i < colModel.length; i++){
        var colId = colModel[i].index ? colModel[i].index : colModel[i].name;
        if(colId == colName){
            return i;
            break;
        };
    };
    return -1;
};

/**
 * Entry function for showing admin basic grids
 *
 * @class gridConfig
 * @constructor
 * @param {String} gridId
 * @param {Integer} orgId
 * @param {Integer} level
 */
var gridConfig = function(gridId, orgId, level){
    var but_ok        = translate.t('JVS_BUT_OK');
    var but_propagate = translate.t('JVS_BUT_PROPAGATE');
    var but_cancel    = translate.t('JVS_BUT_CANCEL');
    var buttons       = {};
    buttons[but_ok]   = function() {
        gridBasicSave(gridId, "/" + lang + "/admin/settings/ajaxc-save-settings?gridid=" + gridId + "&orgid="+orgId+"&level="+level);
        if($("#adminform").length>0){
            $("#adminform").dirtyForms('setDirty');
        }
        $( this ).dialog( "close" );
    };
    buttons[but_propagate] = function() {
        gridBasicSave(gridId, "/" + lang + "/admin/settings/ajaxc-save-and-propagate-settings?gridid=" + gridId + "&orgid="+orgId+"&level="+level);
        if($("#adminform").length>0){
            $("#adminform").dirtyForms('setDirty');
        }
        $( this ).dialog( "close" );
    };
    buttons[but_cancel] = function() {
        $( this ).dialog( "close" );
    };
    $("<div id='gridDialogBox'/>").dialog({
        modal: true,
        buttons: buttons,
        width: $(window).width()*0.9,
        height: "auto",
        draggable : false,
        resizable : false,
        stack : false,
        show: {effect: 'fade', speed: 2000},
        hide: {effect: 'fade', speed : 4000 },
        zIndex : 1002,
        open : function (event, ui) {  $(this).prev().hide(); addBasicGrid(gridId, orgId, level);},
        close : function () { $(this).remove();}
    });
};


/**
 * Event handler: JqGrid's event 'resizeStop'
 */


/**
 * Event handler: JqGrid's event 'resizeStop'
 *
 * @class onGridColumnWidthChanged
 * @constructor
 * @event resizeStop
 * @param {Integer} newwidth
 * @param {Integer} index
 * @param {String} gridId
 * @param {String} url
 */
var onGridColumnWidthChanged = function(newwidth, index, gridId, url){
    mColModel = $("#" + gridId).jqGrid("getGridParam", "colModel");
    curColIndexName =  mColModel[index].index;

    $.ajax({
        url: url + "?gridid=" +gridId + "&colindex=" + curColIndexName + "&width=" + newwidth,
        type: 'GET',
        dataType: "json",
        success: function(data){
                    if(data.message.toLowerCase() == "ok"){
                        trace("[GRID] resizing stored.");
                    }
                 }
        });

};

/**
 * Store admin basic grid config per AJAX call
 *
 * @class gridBasicSave
 * @constructor
 * @param {String} gridId
 * @param {String} url To send ajax call
 */
var gridBasicSave = function(gridId, url){
    var idGrid = "admgrid_" + gridId;
    mColModel = $("#" + idGrid).jqGrid("getGridParam", "colModel");
    data='';
    var remapColumnsAdmin = '';
    var allInternalColumns = gridInternalColumns();
    var countOfInternalCols = gridCountOfInternalColumns(idGrid);
    var remapColumns =   countOfInternalCols > 0 ? createCSNumeration(countOfInternalCols-1) : "0";

    var mapVisibleCols2Order = {};
    var arVisibleCols = new Array();
    var counterVisibleCols = countOfInternalCols > 0 ? countOfInternalCols : 1;

    var map = $("#"+idGrid).jqGrid("getGridParam", "origCol2OrderIndex");

    $.each(mColModel,function(index,column){
        var colId = column.index ? column.index : column.name;
        if(map){
            remapColumnsAdmin += map[colId] + ",";
        }
        if(allInternalColumns.contains(colId))
            return;
        if(column.hidden == false)
            arVisibleCols.push(colId);
        data += colId + '=' + column.hidden + ',' + column.width + '&';

    });
    trace("[GRID] remapColumnsAdmin:" + remapColumnsAdmin);

    defaultColModel = $("#"+idGrid).jqGrid("getGridParam", "defaultColModelOrderMap");
    jQuery.each(defaultColModel, function(name, value) {
        if($.inArray(name, arVisibleCols) > -1)
            mapVisibleCols2Order[name] = counterVisibleCols++;
    });
    for(var i=0; i<arVisibleCols.length; i++) {
        remapColumns += ',' + mapVisibleCols2Order[arVisibleCols[i]] ;
    }

    if(remapColumnsAdmin){
        var re = /,$/;
        remapColumnsAdmin = remapColumnsAdmin.replace(re, "");
        data += "remapColumnsAdmin=" + remapColumnsAdmin;
    }
    data += "&remapColumns=" + remapColumns;
    sortname =  $("#"+idGrid).jqGrid('getGridParam', 'sortname');
    if(sortname)
        data += "&sortname=" + sortname;
    sortorder = $("#"+idGrid).jqGrid('getGridParam', 'sortorder');
    if(sortorder)
        data += "&sortorder=" + sortorder;

    if (data != '')
    {
        $.ajax({
            url: url,
            type: 'POST',
            dataType: "json",
            data: data,
            success: function(data){
                        if(data.error){
                            alert("An error occurred.");
                           // location.reload();//$('#customergrid').trigger("re/loadGrid");
                        } else {
                            if(data.message.match(/^\d+$/)){
                            	// Expect new DB insert ID: store this in hidden field
                                $("input#" + gridId).val(data.message);
                            }
                        }
            }
        });
    };
};

var gridInit = function(gridId){
    var idGrid = "#" + gridId;
    var gridElement = jQuery("#"+gridId);

    var multiselectActions = gridElement.jqGrid("getGridParam", "multiselectActions");

    if (multiselectActions) {

        gridElement.jqGrid("registerMultiselectAction", jQuery.parseJSON(multiselectActions));
    }

    if(gridElement.jqGrid("getGridParam", "origCol2OrderIndex") == "undefined" || !gridElement.jqGrid("getGridParam", "origCol2OrderIndex"))
    {
        colModel = jQuery(idGrid).jqGrid("getGridParam", "colModel");
        var mapOrigCol2OrderIndex = {};
        $.each(colModel,function(index,column, array){
            if(column.index)
                mapOrigCol2OrderIndex[column.index]= index;
            else
                mapOrigCol2OrderIndex[column.name]= index;
        });
        //As colModel order is changed after remapl columns
        jQuery(idGrid).setGridParam({origCol2OrderIndex: mapOrigCol2OrderIndex});
    }

    //var perm = jQuery(idGrid).jqGrid("getGridParam", "remapColumns");
    var mode = jQuery(idGrid).jqGrid("getGridParam", "mode");
    if(mode == "admin"){
        var perm = jQuery(idGrid).jqGrid("getGridParam", "remapColumnsAdmin");
        if(perm == "undefined" || perm == null || !perm){
            trace("[GRID] Columns NOT ordered(remapColumnsAdmin not set)");
            return false;
        }
    }
    else
        var perm = jQuery(idGrid).jqGrid("getGridParam", "remapColumns");

    if(!perm || typeof perm != "string" || !perm.match(/\d+,.*/)){
        trace("[GRID] Columns NOT ordered(no permutation)");
        return false;
    }
    perm = perm.split(",");
    if(perm.length < 1){
        trace("[GRID] Grid columns NOT ordered(perm length)");
        return false;
    }

    trace("[GRID] grid init - Permuatation: " + perm.join(",") + " - length: " + perm.length + " - colModel length: " + gridElement.jqGrid("getGridParam", "colModel").length);
    if (isGridPermValid(gridId) == true) {
        gridElement.jqGrid('remapColumns', perm, true,false);
        return true;
    } else{
        trace("[GRID] Grid columns NOT ordered(invalid perm)");
    }

    return false;
};

/**
* multiselectActions Feature for jqGrid
*
* PLEASE NOTE: do not place module specific functionality here, and use
* the callback functions!
*/
(function($) {
    $.jgrid.extend({
        registerMultiselectAction : function(multiselectActions) {
            return this.each(function(){
                var t = this;

                if (!t.grid) {
                    return;
                }

                var gridId = $(t).attr('id');
                var multiselectActionsId = gridId + '-multiselect-actions';

                if (typeof multiselectActions.wrapper == 'undefined') {
                    throw("No multiselectActions wrapper configured");
                }

                if (typeof multiselectActions.actions == 'undefined') {
                    throw("No multiselectActions actions configured");
                }
                //if($("#" + multiselectActionsId).length == 0) {
                    // Build select html and inject it into the wrapper
                    var multiselectActionsHtml  = '<select class="ui-widget-content ui-corner-all select" id="' + multiselectActionsId + '">';

                    if (typeof multiselectActions.nonSelectedLabel != 'undefined') {
                        multiselectActionsHtml += '<option value="">' +  multiselectActions.nonSelectedLabel + '</option>';
                    }

                    $.each(multiselectActions.actions, function(actionName, actionInformation) {
                        multiselectActionsHtml += '<option value="' + actionName + '">' + actionInformation.label + '</option>';
                    });

                    multiselectActionsHtml += '</select>';

                    $('#' + multiselectActions.wrapper).html(multiselectActionsHtml);
                //}

                var $multiselectElement = $('#' + multiselectActionsId);

                // Bind select change callback, if configured
                if (typeof multiselectActions.callbackUrl != 'undefined'
                    && typeof multiselectActions.callbackFunction != 'undefined') {
                    $multiselectElement.unbind().bind('change', function(event) {
                        // on change, call callbackFunction which handles
                        // the rest individually
                        if (typeof window[multiselectActions.callbackFunction] != 'function') {
                            throw("No callbackFunction registered for multiselectActions");
                        }

                        var fn = window[multiselectActions.callbackFunction];
                        // fn(event, gridId, multiselectActions);
                        fn(event, gridId, multiselectActions);

                        // Set the first multiAction as selected again
                        $multiselectElement.children("option:first").attr("selected", "selected");
                        checkMultiselectCheckboxStatus();
                    });
                }

                // Select actions handler
                // bind event handler to activate select box when at least one checbox is selected
                var checkMultiselectCheckboxStatus = function() {
                        if ($('#' + gridId + ' tr td:first-child input:checked').length > 0) {
                            // this check avoids trouble with multisearch initialisation
                            if ($multiselectElement.hasClass('issetSelect')) {
                                $multiselectElement.multiselect('enable');
                            } else {
                                $multiselectElement.removeAttr('disabled');
                            }
                        } else {
                            if ($multiselectElement.hasClass('issetSelect')) {
                                $multiselectElement.multiselect('disable');
                            } else {
                                $multiselectElement.attr('disabled', true);
                            }
                        }
                };

                // Bind check on all checkbox when they are rendered, and the main switch too
                $('#' + gridId).on("jqGridLoadComplete", function() {

                    $('#' + gridId).bind("jqGridSelectRow", function(event, rowId, z, a, b) {
                        $("#"+rowId, this).find(".cbox").trigger("isChecked");
                    });

                    $('#' + gridId).bind("jqGridSelectAll", function(){
                        $(this).find(".cbox").trigger("isChecked");
                    });

                    checkMultiselectCheckboxStatus();

                    $('#cb_' + gridId).bind('click', checkMultiselectCheckboxStatus);

                    $('#' + gridId).on("jqGridSelectRow", function() {
                        checkMultiselectCheckboxStatus();
                    });
                });

                // run it once to check initial state
                checkMultiselectCheckboxStatus();
            });
        }
    });
})(jQuery);

var numComparisonAsc = function(a, b) {
    return a-b;
};

/**
 * Checks whether requested remap of comlumns is valid
 *
 * @class isGridPermValid
 * @constructor
 * @param {String} gridId
 * @return {Boolean}
 */
var isGridPermValid = function(gridId){
    var idGrid = "#" + gridId;
    var perm = $(idGrid).jqGrid("getGridParam", "remapColumnsAdmin");
    if(perm == "undefined" || perm == null){
        perm = jQuery(idGrid).jqGrid("getGridParam", "remapColumns");
        perm = $(idGrid).jqGrid("getGridParam", "remapColumns").split(",");
    } else {
        perm = perm.split(",");
    }

    var gridColModel = $(idGrid).jqGrid("getGridParam", "colModel");
    if(perm.length != (gridColModel.length)){
        return false;
    }

    permTmp = perm.slice();
    permSorted = permTmp.sort(numComparisonAsc);
    for (var i = 0; i < permSorted.length; i++){
        if( i != permSorted[i]){
            return false;
        };
    }
    return true;
};


/**
 * TODO: bug wrapper for 'remapColumns' as this.p.lastsort is not initialized
 */
var getSortColOrderFromModel = function(gridId){
    ret = 0;
    var grid = $("#" + gridId);
    var gridModel = grid.jqGrid("getGridParam", "colModel");
    var sortname  = grid.jqGrid('getGridParam', 'sortname');
    if(!sortname)
        return ret;
    for (var i = 0; i < gridModel.length; i++){
        var colId = gridModel[i].index ? gridModel[i].index : gridModel[i].name;
        if(colId == sortname){
            ret = i;
            break;
        };
    }
    return ret;
};

/**
 * Check whether current grid has a action column
 *
 * @class gridHasActionsCol
 * @constructor
 *
 * @param {String} gridId
 * @return {Boolean} Returns true on success
 */
var gridHasActionsCol = function(gridId){
    ret = false;
    var grid = $("#" + gridId);
    var gridModel = grid.jqGrid("getGridParam", "colModel");

    for (var i = 0; i < gridModel.length; i++){
        var colId = gridModel[i].index ? gridModel[i].index : gridModel[i].name;
        if(colId == "actions"){
            return true;
            break;
        };
    }
    return ret;
};

/**
 * Check whether current grid has a 'is_deleted' column
 *
 * @class gridHasIsDeletedCol
 * @constructor
 *
 * @param {String} gridId
 * @return {Boolean} Returns true on success
 */
var gridHasIsDeletedCol = function(gridId){
    ret = false;
    var grid = $("#" + gridId);
    var gridModel = grid.jqGrid("getGridParam", "colModel");
    for (var i = 0; i < gridModel.length; i++){
        var colId = gridModel[i].index ? gridModel[i].index : gridModel[i].name;
        if(colId == "is_deleted"){
            return true;
            break;
        };
    }
    return ret;
};

var gridHasColumn = function(gridId, colName){
    ret = false;
    var grid = $("#" + gridId);
    var gridModel = grid.jqGrid("getGridParam", "colModel");
    for (var i = 0; i < gridModel.length; i++){
        var colId = gridModel[i].index ? gridModel[i].index : gridModel[i].name;
        if(colId == colName){
            return true;
            break;
        };
    }
    return ret;
};

/**
 * Count of internal columns
 *
 * @class gridCountOfInternalColumns
 * @constructor
 *
 * @param {String} gridId Grid's ID
 * @return {Integer} Count of internal columns
 */
var gridCountOfInternalColumns = function(gridId){
    curInternalCols = gridGetInternalCols(gridId);
    return curInternalCols.length;
};

/**
 * Array of internal columns of given grid
 *
 * @class gridGetInternalCols
 * @constructor
 *
 * @param {String} gridId Grid's ID
 * @return {Array} Array of internal columns of given grid
 */
var gridGetInternalCols = function(gridId){
    var grid = $("#" + gridId);
    var gridModel = grid.jqGrid("getGridParam", "colModel");
    internalCols = gridInternalColumns();
    result = [];
    for (var i = 0; i < gridModel.length; i++){
        var colId = gridModel[i].index ? gridModel[i].index : gridModel[i].name;
        if (internalCols.contains(colId)) {
            result.push(colId);
        }
    }
    return result;
};

/**
 * Array of internal columns of given grid
 *
 * @class createCSNumeration
 * @constructor
 *
 * @param {Integer} ending number of numeration
 * @param {Boolean} asArray Optional, defaults to false
 * @return {String}|{Array} Comma sep. numeration from 0 to count; Default string
 */
var createCSNumeration = function(count, asArray) {
    var list = [];
    for (var i = 0; i <= count; i++) {
        list.push(i);
    };
    if (asArray != "undefined" && asArray != null && asArray)
        return list;
    return list.join(",");
};

function gridActionsFormatter (cellvalue, options, rowObject) {

    var actionsDiv = $("<div />");

    if(options.colModel.formatoptions)
    if(options.colModel.formatoptions.rowButton)
    {
        $.each(options.colModel.formatoptions.rowButton, function (index,value) {

            if(typeof value != "object")
                trace("[GRID] In rowButton muss ein JS-Object sein");

             var opt = $.extend({
                Click : false,
                Title : false,
                Icon  : 'ui-icon-info',
                UseValue : false,
                Classes : 'ui-state-default'
            },value);

            if(opt.Click)
            {
                if(opt.UseValue !== false)
                    var Bt = $("<button />",{'class':'actionGridIcon '+opt.Classes}).html("<span class='ui-button-text'>"+cellvalue+"</span>").addClass("ui-button ui-widget ui-corner-all ui-button-text-only");
                else
                    var Bt = $("<button />",{'class':'actionGridIcon '+opt.Classes}).html('<span class="ui-button-icon-primary ui-icon '+opt.Icon+'"></span><span class="ui-button-text">&nbsp;</span>').addClass("ui-button ui-widget ui-corner-all ui-button-icon-only");

                Bt.attr("onmouseOver","buttonHover(this, '"+options.rowId+"');");
                Bt.attr("onmouseOut","buttonOut(this, '"+options.rowId+"');");
                if(opt.Click)
                {
                    Bt.attr("onclick",opt.Click+"('"+options.rowId+"', this)");
                }

                if(opt.Title)
                {
                     Bt.addClass("tooltip").attr("title",opt.Title);
                }

                if(opt.UseValue !== false && $.trim(cellvalue) == "")
                    Bt = $("<span/>");

                actionsDiv.append(Bt);
            }
        });
    }

    return actionsDiv.html();
}

function buttonHover(element, rowId){
    $(element).addClass("ui-state-hover");
    Tipped.remove('#'+rowId);
}

function buttonOut(element, rowId){
    $(element).removeClass("ui-state-hover");
    Tipped.create($('#'+rowId),{
            skin: 'light',
            showDelay: 2000,
            zIndex: 8889,
            hook: 'topleft',
            target : "mouse",
            onShow : getGridRowData
        });
}

/**
* Add Toolbar Search to a grid
* Also cares about adding validators, if specified
*
* @function addGridToolbarSearch
* @param {String} gridId - The element ID of the grid
* @return {void}
*/
function addGridToolbarSearch(gridId) {
    var gridElement = jQuery("#"+gridId);

    if (!gridElement) {
        return;
    }

    gridElement.data('firstSearch',true);

    $.xhrPool = [];
    $.xhrPool.abortAll = function() {
        $(this).each(function(idx, jqXHR) {
        jqXHR.abort();
        });
    };

    gridElement.get(0).p.ajaxGridOptions.beforeSend = function (xhr) { $.xhrPool.push(xhr); if(jQuery("#"+gridId).data('firstSearch') == true){ $.xhrPool.abortAll();  jQuery("#"+gridId).data('firstSearch',false); jQuery("#"+gridId)[0].triggerToolbar(); }  };
    gridElement.get(0).p.ajaxGridOptions.ajaxComplete = function () { $.xhrPool.pop();};
    gridElement.filterToolbar({stringResult: true,searchOnEnter : false, beforeSearch : function() {
        $.xhrPool.abortAll();
    }});

    $(".ui-search-toolbar input[type=text]","#gview_"+gridId).not(".issetClearInput, #search").clearInput();

    // Check if there should be any validation for this grid / toolbar
    var toolbarSearchValidation = gridElement.getGridParam("toolbarSearchValidation");

    if (toolbarSearchValidation) {
        toolbarSearchValidation = jQuery.parseJSON(toolbarSearchValidation);

        $.each(toolbarSearchValidation, function(fieldId, validatorInfo) {
            gridToolbarSearchValidator(fieldId, validatorInfo);
        });
    }
}

/**
* Add validator for a Toolbar Search
*
* @class bindGridToolbarSearchValidator
* @param {String} fieldId       - ID of the element to validate
* @param {String} validatorInfo - Information abot the validator
* @return {void}
*/
function gridToolbarSearchValidator(fieldId, validatorInfo) {
    this.isNumeric = function(key, event) {

        var isSpecialKey = event.shiftKey || event.altKey || event.ctrlKey;

        var inp = String.fromCharCode(key);

        if (/[0-9]/.test(inp) && !isSpecialKey) {
            return true;
        }

        return false;
    };

    this.isAlpha = function(key, event) {
        if (key >= 65 && key <= 90) {
            return true;
        }

        return false;
    };

    this.isAdditionalKeyCode = function(key, additionalKeyCodes, event) {
        if (additionalKeyCodes && additionalKeyCodes.indexOf(key) >= 0) {
           return true;
        }

        return false;
    };

    for (var validatorName in validatorInfo) {
        switch (validatorName) {
            // KeyFilter
            // types: numeric, alphaNumeric
            case 'keyFilter':
                if (typeof validatorInfo[validatorName].type == 'undefined') {
                    trace ("No type defined for '" + validatorName + "' toolbar search validator");

                    break;
                }

                var parent = this;

                $('#' + fieldId).bind('keypress', function(evt) {
                    evt = evt || window.event;
                    var key = evt.which || evt.keyCode;
                    var result = null;

                    // Always allowed control keys:
                    // backspace, tab, left arrow, right arrow, del
                    if (key == 8 || key == 9 || key == 37 || key == 39 || key == 46) {
                        return true;
                    }

                    if (typeof validatorInfo[validatorName].additionalKeyCodes != 'undefined') {
                        additionalKeyCodes
                            = validatorInfo[validatorName].additionalKeyCodes;
                    } else {
                        additionalKeyCodes = false;
                    }

                    switch(validatorInfo[validatorName].type) {
                        case 'numeric':
                            result = parent.isNumeric(key, evt)
                                        || parent.isAdditionalKeyCode(key, additionalKeyCodes, evt);
                            break;

                        case 'alphaNumeric':
                        default:
                            result = parent.isNumeric(key, evt)
                                        || parent.isAlpha(key, evt)
                                        || parent.isAdditionalKeyCode(key, additionalKeyCodes, evt);
                            break;
                    }

                    if (!result) {
                        evt.returnValue = false;
                        evt.preventDefault();
                        evt.stopPropagation();
                        evt.stopImmediatePropagation();
                        return false;
                    }
                });
                break;
        }
    }
}

$.fn.setGridRowTooltip = function () {

    var target = "mouse";

    return this.each(function(){
        Tipped.create($(this).attr("title", ""),{
            skin: 'light',
            showDelay: 2000,
            zIndex: 8889,
            hook: 'topleft',
            target : target,
            onShow : getGridRowData
        });
    }) ;
}

function getGridRowData (content, element) {
    var gridId = $(element).parents("table").get(0).id;
    var headerTh = $("table.ui-jqgrid-htable tr.ui-jqgrid-labels th.ui-th-column div.ui-jqgrid-sortable", "#gview_"+gridId);
    var mainDiv = $("<div />", {'class' : 'ib','style' : 'white-space: nowrap;'});
    var divLeft = $("<div />", {'class' : 'fl bt', 'style' : 'padding-right:5px;'});
    var divRight = $("<div />", {'class' : 'fl'});
    var dataObj = {};

    headerTh.each(function(){
        var textCon = $(this);
        if(textCon.get(0).id.indexOf("actions") == -1 && textCon.is(':visible')) {
            dataObj[textCon.get(0).id.replace(/jqgh_/,'')] = textCon.text();
        }
    });

   $.each(dataObj,function(i,v){
       divLeft.append("<div>"+v+"</div>");
       var _td =  $("td[aria-describedby="+i+"]",element);
       var _selbox = _td.find("select");
       var text = _td.text();

       if (text == "") {
          var checkbox = _td.find("input[type=checkbox]");

          if (checkbox && checkbox.length > 0) {
            if (checkbox.is(":checked")) {
                text = translate.t("JVS_LAB_YES");
            } else {
                text = translate.t("JVS_LAB_NO");
            }
          }
       }

       if (_selbox.length == 0) {
           if (text == "")
              text = "&nbsp;";

            divRight.append("<div>"+text+"</div>");
       } else {
            divRight.append("<div>"+_selbox.find("option:selected").text()+"</div>");
       }
   });

   mainDiv.append(divLeft).append(divRight);

   $(content).html(mainDiv);

   var w1 = divLeft.outerWidth();
   var w2 = divRight.outerWidth();

   var size = mainDiv.css("font-size");

   mainDiv.css('width', (w1+w2+10)/size.replace(/px/,"")+"em");

   Tipped.refresh(element);
}

/**
* Custom Grid formatter
*
* Allows specifying an onclick function
*
* formatter: 'checkboxUpdaterFmatter',
* formatoptions: { onclickFunction: 'myFunctionName', onclickId: 'idcol' }
*
* where onclickId is the name of the column with the dataset id
*
* onclick function has to expect 2 parameters:
* element -> pointer to the element that invoked the click (this)
* id -> ID that has been clicked
*
* function myFunctionName(element, id) {
*    trace($(element).attr('checked'));
*    trace(id);
* }
*
*/
$.fn.fmatter.checkboxUpdaterFmatter = function (cval, opts, rowObject)
{
    var op = $.extend({},opts.checkbox), ds;
    if(!$.fmatter.isUndefined(opts.colModel.formatoptions)) {
        op = $.extend({},op,opts.colModel.formatoptions);
    }
    if($.fmatter.isEmpty(cval) || $.fmatter.isUndefined(cval) ) {cval = $.fn.fmatter.defaultFormat(cval,op);}
    cval=cval+"";cval=cval.toLowerCase();
    var bchk = cval.search(/(false|0|no|off)/i)<0 ? " checked='checked' " : "";

    var onclick = '';

    if(typeof opts.colModel.formatoptions != 'undefined') {
        if (typeof opts.colModel.formatoptions.onclickFunction == 'undefined'
            || typeof opts.colModel.formatoptions.onclickId == 'undefined') {
            // console.log("no onclickFunction or onclickId defined");
        }

        var updateId = rowObject[opts.colModel.formatoptions.onclickId];

        onclick = 'onclick="' + opts.colModel.formatoptions.onclickFunction + '(this, ' + updateId + ');"';

        if(typeof opts.colModel.formatoptions.attributes != 'undefined') {
            onclick += " " + opts.colModel.formatoptions.attributes;
        }
    } else {onclick="";}

    return "<input data-rowid=\"1\" type=\"checkbox\" " + bchk  + " value=\""+ cval+"\" offval=\"no\" "+onclick+ "/>";
};

var setGridMarksChecked = function setGridMarksChecked(gridid) {
    if($('#'+gridid).get(0).p.gridMarksCount > 0)
        $('#'+gridid+'-multiselect-actions').removeAttr("disabled").multiselect("enable");
}

$.jgrid.extend({
            expandRow : function(record) {
                this.each(function() {
                    var $t = this;
                    if (!$t.grid || !$t.p.treeGrid) {
                        return;
                    }
                    var childern = $($t).jqGrid("getNodeChildren", record), //if ($($t).jqGrid("isVisibleNode",record)) {
                    expanded = $t.p.treeReader.expanded_field;
                    $(childern).each(
                            function(i) {
                                var id = $.jgrid.getAccessor(this,
                                        $t.p.localReader.id);
                                //$("#"+id,$t.grid.bDiv).css("display","");
                                $("#" + $.jgrid.jqID(id)).css("display", "");
                                if (this[expanded]) {
                                    $($t).jqGrid("expandRow", this);
                                }
                            });
                    //}
                });
            },
            collapseRow : function(record) {
                this
                        .each(function() {
                            var $t = this;
                            if (!$t.grid || !$t.p.treeGrid) {
                                return;
                            }
                            var childern = $($t).jqGrid("getNodeChildren",
                                    record), expanded = $t.p.treeReader.expanded_field;
                            $(childern).each(
                                    function(i) {
                                        var id = $.jgrid.getAccessor(this,
                                                $t.p.localReader.id);
                                        //$("#"+id,$t.grid.bDiv).css("display","none");
                                        $("#" + $.jgrid.jqID(id)).css(
                                                "display", "none");
                                        if (this[expanded]) {
                                            $($t).jqGrid("collapseRow", this);
                                        }
                                    });
                        });
            }
        });

/**
 * Adapts enter to edit
 *
 */
var stdBindKeysHandler = function stdBindKeysHandler(gridId) {
    if(!gridId || typeof gridId == undefined)
        return;
    grid = "#" + gridId;
    //$("#adminCompanygrid").jqGrid("setSelection", "11");

    if($(grid).jqGrid("getGridParam", "editurl") == 'edit') {
        $(grid).jqGrid('bindKeys', {
            onEnter: function(rowid) {
                editingRowId = rowid;
                jqgridEditIcon = $(grid).find("tr#" + rowid + " div.ui-pg-div.ui-inline-edit");
                if(jqgridEditIcon.size()<1){
                    editButton = $(grid).find("tr#" + rowid + " td.actions button.actionGridIcon");
                    if(editButton.size()>0)
                        editButton.trigger('click');
                } else {
                    jqgridEditIcon.trigger('click');
                }
            }}
        );
        ids = $(grid).jqGrid("getDataIDs");
        if(ids && ids.length > 0)
            $(grid).jqGrid("setSelection", ids[0]);
    } else{
        $(grid).jqGrid('bindKeys');
    }
};
